package com.blog.dao.conn;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;





/**
 * 
 * 
 * @author Administrator
 *
 */

public class BaseDao {

	static DataSource ds = null;

	public BaseDao() {
		try {
			// ��ʼ������
			Context ctx = new InitialContext();
			synchronized (this) {
				if (ds == null) {
					// ��ȡ����Դ
					ds = (DataSource) ctx.lookup("java:/comp/env/jdbc/blog");
				}
			}

		} catch (NamingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 
	 */
	public Connection getConnection() throws SQLException {
		return ds.getConnection();
	}

	public int updateExecuted(String sql) {
		return this.updateExecuted(sql, null);
	}

	public int updateExecuted(String sql, ParamSetimpl params) {
		int row = 0;
		Connection con = null; // ���ݿ����Ӷ���
		PreparedStatement ps = null;
		try {
			con = getConnection();
			// 3.ִ��sql���
			ps = con.prepareStatement(sql);
			// ���ò���
			if (params != null) {
				// ���ò������÷���
				params.setParams(ps);
			}
			// ִ��SQL
			row = ps.executeUpdate();

		} catch (SQLException e) {

			e.printStackTrace();
		} finally {
			// �ر����Ӷ���
			this.close(con, ps, null);
		}
		return row;
	}
	public <T> T query(String sql,RowDatas<T> rd) {
		return query(sql, null, rd);
	}

	
	public <T> T query(String sql, ParamSetimpl params,RowDatas<T> rd) {
		
		List<T> lst = queryList(sql, params, rd);
		if(lst!=null && lst.size()>0){
			return lst.get(0);
		}
		return null;
	}

	
	public <T> List<T> queryList(String sql,RowDatas<T> rd) {		
		
		return queryList(sql, null, rd);
	}

	
	public <T> List<T> queryList(String sql, ParamSetimpl params,RowDatas<T> rd) {
		List<T> lst = new ArrayList<T>();
		Connection con = null; // ���ݿ����Ӷ���
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			con = getConnection();
			// 3.��ȡSQLִ�ж���
			ps = con.prepareStatement(sql);
			// ���ò���
			if (params != null) {
				// ���ò������÷���
				params.setParams(ps);
			}
			rs = ps.executeQuery();		
			// 4. ��������
			while (rs.next()) {	
				// ���������ӵ�List��
				lst.add(rd.getRowData(rs));
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			// �ر����Ӷ���
			this.close(con,ps,rs);
		}
		// ����list����
		return lst;
	}

	/**
	 * �ر����ݿ�����
	 * 
	 * @param rs
	 * @param ps
	 * @param con
	 */
	public void close(Connection con, PreparedStatement ps, ResultSet rs) {
		// �ر�ResultSet ���������
		if (rs != null) {
			try {
				rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		// �ر�PrepareStatement SQLִ�ж���
		if (ps != null) {
			try {
				ps.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		// �ر�Connection ���Ӷ���
		if (con != null) {
			try {
				con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
	public <T> T query(String sql,Class<T> cls ) {
		return query(sql, null, cls);
	}
	/**通过反射机制查询单条记录
	 * @param sql
	 * @param params
	 * @param cls
	 * @return
	 * @throws Exception
	 */
	public <T> T query(String sql, ParamSetimpl params,
			Class<T> cls ){
		T resultObject = null;
		int index = 1;
		Connection con = null; // ���ݿ����Ӷ���
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			con = getConnection();
			pstmt = con.prepareStatement(sql);
			if (params != null) {
				// ���ò������÷���
				params.setParams(pstmt);
			}
			rs = pstmt.executeQuery();
			ResultSetMetaData metaData  = rs.getMetaData();
			int cols_len = metaData.getColumnCount();
			while(rs.next()){
				//通过反射机制创建一个实例
				resultObject = cls.newInstance();
				for(int i = 0; i<cols_len; i++){
					String cols_name = metaData.getColumnName(i+1);
					Object cols_value = rs.getObject(cols_name);
					/*if(cols_value == null){
						cols_value = "";
					}*/
					Field field = cls.getDeclaredField(cols_name);
					field.setAccessible(true); //打开javabean的访问权限
					field.set(resultObject, cols_value);
				}
			}
		} catch (SQLException | InstantiationException | IllegalAccessException | NoSuchFieldException | SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			// �ر����Ӷ���
			this.close(con, pstmt, rs);
		}
	
		return resultObject;

	}
	public  <T> List<T> queryList(String sql,Class<T> cls ){
		return queryList(sql, null,cls );
	}
	/**通过反射机制查询单条记录
	 * @param sql
	 * @param params
	 * @param cls
	 * @return
	 * @throws Exception
	 */
	public  <T> List<T> queryList(String sql, ParamSetimpl params,
			Class<T> cls ){
		List<T> list = new ArrayList<T>();
		int index = 1;
		Connection con = null; // ���ݿ����Ӷ���
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			con = getConnection();
			pstmt = con.prepareStatement(sql);
			if (params != null) {
				// ���ò������÷���
				params.setParams(pstmt);
			}
			rs = pstmt.executeQuery();
			ResultSetMetaData metaData  = rs.getMetaData();
			int cols_len = metaData.getColumnCount();
			while(rs.next()){
				//通过反射机制创建一个实例
				T resultObject = cls.newInstance();
				for(int i = 0; i<cols_len; i++){
					String cols_name = metaData.getColumnName(i+1);
					Object cols_value = rs.getObject(cols_name);
					/*if(cols_value == null){
						cols_value = "";
					}*/
					Field field = cls.getDeclaredField(cols_name);
					field.setAccessible(true); //打开javabean的访问权限
					field.set(resultObject, cols_value);
				}
				list.add(resultObject);
			}
		} catch (SQLException | InstantiationException | IllegalAccessException | NoSuchFieldException | SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			// �ر����Ӷ���
			this.close(con, pstmt, rs);
		}
	
		return list;

	}
	
	
}
